`timescale 1ns/1ps
`default_nettype none
// 本模块主要是处理第一次读SDRAM 来一行的数据存进ram中
/* NOTE:
* - 按灯板的一行缓冲数据
*/

module line_row_buf (
    // system signal
    input  wire         I_sclk,  // 125M
    input  wire         I_rst_n,

    // input pixel
    input  wire         I_pixel_valid, // 像素有效
    input  wire [9:0]   I_pixel_col,   // 像素地址
    input  wire         I_pixel_buf_wsel,
    input  wire [23:0]  I_pixel_gray,  // 像素数据
    input  wire         I_pixel_clk,
    
    // line output
    input  wire         I_pixel_start,    //开始处理像素
    input  wire         I_pixel_buf_rsel,
    input  wire         I_pixel_req,   // 请求读取本行数据 第二次存sdram
    output wire [7:0]   O_pixel_data   // 像素数据 
);
//------------------------Local signal-------------------
// ram
wire        ram0_wren;
wire [9:0]  ram0_waddr;
wire [23:0] ram0_data;
wire        ram0_rden;
wire [9:0]  ram0_raddr;
wire [23:0] ram0_q;
wire        ram1_wren;
wire [9:0]  ram1_waddr;
wire [23:0] ram1_data;
wire        ram1_rden;
wire [9:0]  ram1_raddr;
wire [23:0] ram1_q;
// reg         ram_wsel;
reg         ram_rsel;
wire        ram_rden/* synthesis keep="1" */;
reg  [9:0]  ram_raddr;
// reg         line_start;
// reg         line_end ;
// line output
reg  [2:0]  color;
reg  [7:0]  pixel_buf;
// reg         row_start;
// reg         read_req;

//ram_wsel
always  @(posedge I_sclk or negedge I_rst_n)
    if(~I_rst_n)begin
        ram_rsel <= 'b0;
    end
    else if(I_pixel_start)begin
        ram_rsel <= I_pixel_buf_rsel;
    end

//------------------------Instantiation------------------
// sdpram_1024x24
sdpram_1024x24 ram0 (/*{{{*/
    .data      ( ram0_data ),
    .rdaddress ( ram0_raddr ),
    .rdclock   ( I_sclk ),
    .rden      ( ram0_rden ),
    .wraddress ( ram0_waddr ),
    .wrclock   ( I_pixel_clk ),
    .wren      ( ram0_wren ),
    .q         ( ram0_q )
);/*}}}*/
// sdpram_lpm #(
// .A_ADDRESS_WIDTH (10),
// .A_DATA_WIDTH (24),
// .B_ADDRESS_WIDTH (10),
// .B_DATA_WIDTH (24)
// )
// ram0(
    // .clka           ( I_pixel_clk ),
    // .wea            ( ram0_wren ),
    // .addra          ( ram0_waddr ),
    // .dina           ( ram0_data ),

    // .clkb           ( I_sclk ),
    // .reb            ( ram0_rden ),
    // .addrb          ( ram0_raddr ),
    // .doutb          ( ram0_q )
// );
// // sdpram_1024x24
sdpram_1024x24 ram1 (/*{{{*/
    .data      ( ram1_data ),
    .rdaddress ( ram1_raddr ),
    .rdclock   ( I_sclk ),
    .rden      ( ram1_rden ),
    .wraddress ( ram1_waddr ),
    .wrclock   ( I_pixel_clk ),
    .wren      ( ram1_wren ),
    .q         ( ram1_q )
);/*}}}*/

// sdpram_lpm #(
// .A_ADDRESS_WIDTH (10),
// .A_DATA_WIDTH (24),
// .B_ADDRESS_WIDTH (10),
// .B_DATA_WIDTH (24)
// )
// ram1(
    // .clka           ( I_pixel_clk ),
    // .wea            ( ram1_wren ),
    // .addra          ( ram1_waddr ),
    // .dina           ( ram1_data ),

    // .clkb           ( I_sclk ),
    // .reb            ( ram1_rden ),
    // .addrb          ( ram1_raddr ),
    // .doutb          ( ram1_q )
// );

//{{{+++++++++++++++++++++ram++++++++++++++++++++++++++++
assign ram0_wren  = (I_pixel_buf_wsel== 1'b0) && I_pixel_valid;
assign ram0_waddr = I_pixel_col[9:0];
assign ram0_data  = I_pixel_gray;
assign ram0_rden  = ram_rden;
assign ram0_raddr = ram_raddr;

assign ram1_wren  = (I_pixel_buf_wsel == 1'b1) && I_pixel_valid;
assign ram1_waddr = I_pixel_col[9:0];
assign ram1_data  = I_pixel_gray;
assign ram1_rden  = ram_rden;
assign ram1_raddr = ram_raddr;
reg ram_rden_r;
assign ram_rden = (I_pixel_req && color[2]) || ram_rden_r;

always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        ram_rden_r <= 1'b0;
    else if (I_pixel_start)
        ram_rden_r <= 1'b1;
    else 
        ram_rden_r <= 1'b0;
end

// ram_raddr
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        ram_raddr <= 1'b0;
    else if (I_pixel_start) 
        ram_raddr <= 1'b0;
    else if (ram_rden)
        ram_raddr <= ram_raddr + 1'b1;
end
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++
//{{{+++++++++++++++++++++line output++++++++++++++++++++
assign O_pixel_data = pixel_buf;
// color
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        color <= 3'b001;
    else if (I_pixel_start)
        color <= 3'b001;
    else if (I_pixel_req)
        color <= {color[1:0], color[2]};
end

// pixel_buf
always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n)
        pixel_buf <= 1'b0;
    else if (I_pixel_req) begin
        if (ram_rsel == 1'b0) begin
            if (color[0])
                pixel_buf <= ram0_q[7:0];
            else if (color[1])
                pixel_buf <= ram0_q[15:8];
            else
                pixel_buf <= ram0_q[23:16];
        end
        else begin
            if (color[0])
                pixel_buf <= ram1_q[7:0];
            else if (color[1])
                pixel_buf <= ram1_q[15:8];
            else
                pixel_buf <=ram1_q[23:16];
        end
    end
end


endmodule

`default_nettype wire

// vim:set ts=4 sw=4 et fenc=utf-8 fdm=marker:
